#pragma once

#include "../Math/Vec2i.h"
#include "../Math/Vec3f.h"
#include <libtcod\libtcod.hpp>
#include <memory>
#include <string>
#include <vector>

enum TerrainId
{
	TERRAIN_GROUND,
	TERRAIN_GROUND_FROZEN,
	TERRAIN_GRASS_NORMAL,
	TERRAIN_GRASS_LUSH,
	TERRAIN_GRASS_SPARSE,
	TERRAIN_GRASS_WITHERED,
	TERRAIN_GRASS_DRIED,
	TERRAIN_DIRT,
	TERRAIN_ROCK_BARE,
	TERRAIN_ROCK_DIRTY,
	TERRAIN_GRANITE_SMOOTH,
	TERRAIN_GRANITE,
    TERRAIN_GRANITE_ROUGH,
	TERRAIN_SNOW_SHALLOW,
    TERRAIN_SNOW_NORMAL,
    TERRAIN_SNOW_DEEP,
    TERRAIN_SHALLOW_WATER,
    TERRAIN_DEEP_WATER,
	TERRAIN_SAND,
	TERRAIN_TYPE_ID_COUNT
};

struct TerrainTypeParams
{
	TerrainId id;
	std::string type;
	TCODColor bkgr_color;
	TCODColor frgr_color;
	uint8 frgr_symbol;
	bool has_symbol;
	bool walkable;
	bool swimmable;
	float walkCost;
	float shininess;
	TerrainTypeParams(
		TerrainId id,
		std::string type,
		TCODColor bkgr_color,
		TCODColor frgr_color,
		uint8 frgr_symbol,
		bool walkable,
		bool swimmable,
		float walkCost,
		float shininess)
		: id(id), type(type), bkgr_color(bkgr_color), frgr_color(frgr_color), frgr_symbol(frgr_symbol),
		 walkable(walkable), swimmable(swimmable), walkCost(walkCost), shininess(shininess)
	{}
};

struct TerrainType
{
	TerrainId id;
	std::string type;
	TCODColor bkgr_color;
	TCODColor frgr_color;
	Vec3f bkgr_color_f;
	Vec3f frgr_color_f;
	uint8 frgr_symbol;
	bool walkable;
	bool swimmable;
	float walkCost;
	float shininess;
	TerrainType(const TerrainTypeParams &params)
		: id(params.id), type(params.type), bkgr_color(params.bkgr_color),  frgr_color(params.frgr_color), frgr_symbol(params.frgr_symbol),
		  walkable(params.walkable), swimmable(params.swimmable), walkCost(params.walkCost), shininess(params.shininess)
	{
		bkgr_color_f = Vec3f((float)bkgr_color.r / 255.0f, (float)bkgr_color.g / 255.0f, (float)bkgr_color.b / 255.0f);
		frgr_color_f = Vec3f((float)frgr_color.r / 255.0f, (float)frgr_color.g / 255.0f, (float)frgr_color.b / 255.0f);
	}
};
typedef std::shared_ptr<TerrainType> TerrainTypePtr;

class TerrainTypeManager
{
public:
	TerrainTypeManager();
	~TerrainTypeManager();

	const TerrainTypePtr &getTerrainType(TerrainId type) const;

private:
	std::vector<TerrainTypePtr> types;
};
typedef std::shared_ptr<TerrainTypeManager> TerrainTypeManagerPtr;